home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / www / src / fminit2.0 / mif2html.l < prev    next >
Encoding:
Text File  |  1992-11-17  |  24.4 KB  |  1,058 lines

  1. ;; init.lsp -- init XLisp global environment
  2. ;;
  3.  
  4. (defun require (package)
  5.   (unless (get package 'provided)
  6.       (or (load (concatenate 'string (string-downcase package) ".ol"))
  7.           (load (concatenate 'string (string-downcase package) ".l"))
  8.           (load (concatenate 'string (string-downcase package) ".lsp"))
  9.           (error "can't load package" package))
  10.       ) )
  11.  
  12. (defun provide (package)
  13.   (setf (get package 'provided) t)
  14.   )
  15.  
  16.  
  17. ; from 2.1almy...
  18. ; initialization file for XLISP 2.0
  19.  
  20. (unless (fboundp 'strcat) ; backwards compatibility if COMMONLISP defined
  21.     (defmacro strcat (&rest str) `(concatenate 'string ,@str)))
  22.  
  23.  
  24. ; define some macros
  25. (defmacro defvar (sym &optional val)
  26.   `(if (boundp ',sym) ,sym (setq ,sym ,val)))
  27. (defmacro defparameter (sym val)
  28.   `(setq ,sym ,val))
  29. (defmacro defconstant (sym val)
  30.   `(setq ,sym ,val))
  31.  
  32. ; (makunbound sym) - make a symbol value be unbound
  33. (defun makunbound (sym) (setf (symbol-value sym) '*unbound*) sym)
  34.  
  35. ; (fmakunbound sym) - make a symbol function be unbound
  36. (defun fmakunbound (sym) (setf (symbol-function sym) '*unbound*) sym)
  37.  
  38. ; (mapcan fun list [ list ]...)
  39. (defmacro mapcan (&rest args) `(apply #'nconc (mapcar ,@args)))
  40.  
  41. ; (mapcon fun list [ list ]...)
  42. (defmacro mapcon (&rest args) `(apply #'nconc (maplist ,@args)))
  43.  
  44. ; initialize to enable breaks and trace back
  45. (setq *breakenable* t)
  46. (setq *tracenable* nil)
  47. (alloc 50000)
  48. ;; functions missing that are part of common lisp, and commonly used
  49.  
  50. ;; push and pop treat variable v as a stack
  51.  
  52. (defmacro push (v l)
  53.     `(setf ,l (cons ,v ,l)))
  54.  
  55. (defmacro pop (l)
  56.     `(prog1 (first ,l) (setf ,l (rest ,l))))
  57.  
  58. ;; pairlis does not check for lengths of keys and values being unequal
  59.  
  60. (defun pairlis (keys values list)
  61.     (do ((remkeys keys (rest remkeys))
  62.      (remvals values (rest remvals))
  63.      (newalist list
  64.            (cons (cons (first remkeys) (first remvals)) newalist)))
  65.     ((null remkeys) newalist)
  66.      ))
  67.  
  68.  
  69. (defun copy-list (list) (append list 'nil))
  70.  
  71. (defun copy-alist (list)
  72.     (if (null list)
  73.         'NIL
  74.         (cons (if (consp (car list))
  75.           (cons (caar list) (cdar list))
  76.           (car list))
  77.           (my-copy-alist (cdr list)))))
  78.  
  79. (defun copy-tree (list)
  80.     (if (consp list)
  81.         (cons (copy-tree (car list)) (copy-tree (cdr list)))
  82.         list))
  83.  
  84. (defun list* (&rest list)
  85.     (cond ((null list) 'nil)
  86.       ((null (cdr list)) (car list))
  87.       (t (do* ((head (cons (car list) 'nil))
  88.            (current head
  89.                 (cdr (rplacd current (cons (car tail) 'nil))))
  90.            (tail (cdr list) (cdr tail)))
  91.           ((null (cdr tail)) (rplacd current (car tail)) head)
  92.           ))))
  93.  
  94. ;; THE CAR OF A TCONC POINTS TO THE TCONC LIST,
  95. ;; THE TAIL POINTS TO LAST ELEMENT
  96.  
  97. (defun make-tconc nil
  98.     (cons 'nil 'nil))
  99.  
  100. (defun tconc (tc new)
  101.     (let ((newl (cons new 'nil)))
  102.       (if (null (cdr tc))
  103.       (rplaca tc newl)
  104.       (rplacd (cdr tc) newl))
  105.       (rplacd tc newl)
  106.       tc))
  107.  
  108. (defun lconc (tc list)
  109.     (cond ((not (null list))
  110.        (if (null (cdr tc))
  111.            (rplaca tc list)
  112.            (rplacd (cdr tc) list))
  113.        (rplacd tc (last list))))
  114.     tc)
  115.  
  116. (defun remove-head (tc)
  117.     (cond ((null (car tc)) 'nil)
  118.       ((null (cdar tc))
  119.        (let ((element (caar tc)))
  120.          (rplaca tc 'nil)
  121.          (rplacd tc 'nil)
  122.          element))
  123.       (t (let ((element (caar tc)))
  124.            (rplaca tc (cdar tc))
  125.            element))))
  126.  
  127. (provide 'common)
  128. ;; objective-lisp.l -- syntactic extensions to XLisp for OOP
  129. ;;
  130.  
  131. ;
  132. ; extend reader syntax so that [obj args...]
  133. ; reads as (send obj args...)
  134. ;
  135.  
  136. (setf (aref *readtable* (char-int #\[)) ; #\[ table entry
  137.       (cons :tmacro
  138.         (lambda (f c &aux ex ret)    ; second arg is not used
  139.           (do ()
  140.           ((eq (non-comment-char f) #\]))
  141.           (let ((cell (cons (read f) nil))
  142.             )
  143.             (if ex (setf (cdr ex) cell) (setf ret cell))
  144.             (setf ex cell)))
  145.           (read-char f)        ; toss the trailing #\)
  146.           (cons (cons 'send ret) NIL))
  147.         ))
  148.  
  149. (setf (aref *readtable* (char-int #\]))
  150.       (cons :tmacro
  151.         (lambda (f c)
  152.           (error "misplaced right bracket"))))
  153.  
  154.  
  155. (defun non-comment-char (f)
  156.   (do ((c (peek-char t f) (peek-char t f))
  157.        )
  158.       ((not (eq (aref *readtable* (char-int c))
  159.         (aref *readtable* (char-int #\;))))
  160.        c)
  161.       (read-line f)
  162.       ) )
  163.  
  164.  
  165. ;
  166. ; defclass, defmethod forms
  167. ;
  168.  
  169. ;
  170. ; (defmethod _class_ :selector (args) body...)
  171. ; adds a method to _class_
  172. ;
  173. (defmacro defMethod (cls message arglist &rest body)
  174.   `[,cls :answer ',message ',arglist
  175.      ',body]
  176.   )
  177.  
  178. (defMethod Class :SET-PNAME (NAME)
  179.   (SETF PNAME (STRING NAME))
  180.   )
  181.  
  182. ;
  183. ; (defClassMethod _class_ :selector (args) body...)
  184. ; adds a method to _class_'s metaclass.
  185. ;
  186. (defmacro defClassMethod (cls message arglist &rest body)
  187.   `[[,cls :class] :answer ,message ',arglist
  188.     ',body]
  189.   )
  190.  
  191. ;
  192. ; In order to have class methods, every normal class
  193. ; is an instance of a metaclass. All the metaclasses
  194. ; are instances of class.
  195. ;
  196.  
  197. ;
  198. ; Create the root of the metaclass hierarchy
  199. ;
  200.  
  201. (setf MetaClass [Class :new () () Class])
  202. [MetaClass :set-pname 'MetaClass]
  203.  
  204. (defMethod Class :for (name super)
  205.   (let ((mc [MetaClass :new () () [super :class]])
  206.     )
  207.     [mc :set-pname (concatenate 'string (string name) "-MetaClass")]
  208.     mc
  209.     ) )
  210.  
  211. ;
  212. ; Create a class and its metaclass.
  213. ;
  214.  
  215. (defmacro defClass (cl super &optional ivars cvars)
  216.   (if (null super) (setq super 'Object))
  217.   `(let ((mc [MetaClass :for ',cl ,super])
  218.      )
  219.      (setf ,cl [mc :new ',ivars ',cvars ,super])
  220.      [,cl :set-pname ',cl]
  221.      )
  222.   )
  223.  
  224. (provide 'objective-lisp)
  225. ;; stream.ol
  226.  
  227. (require 'objective-lisp)
  228.  
  229. (defClass Stream ()
  230.   (stream)
  231.   )
  232.  
  233. (defMethod Stream :isnew (s)
  234.   (setf stream s)
  235.   self
  236.   )
  237.  
  238. (defClass IStream Stream
  239.   ()
  240.   (common-lisp-read-table)
  241.   ;; *readtable* is a class variable of IStream
  242.   )
  243.  
  244. (defMethod IStream :isnew (s)
  245.   (send-super :isnew s)
  246.   (unless common-lisp-read-table
  247.       (setq common-lisp-read-table *readtable*)) ;;HACK
  248.   self
  249.   )
  250.  
  251. (defClassMethod IStream :open (fn)
  252.   [self :new (open fn)]
  253.   )
  254.  
  255. (defMethod IStream :set-readtable (&optional tbl)
  256.   (setq *readtable* (or tbl common-lisp-read-table))
  257.   )
  258.  
  259. (defMethod IStream :read (&optional eof)
  260.   (read stream eof)
  261.   )
  262.  
  263. (defClass OStream Stream
  264.   ()
  265.   )
  266.  
  267. (defMethod OStream :format (form &rest args)
  268.   (apply #'format (append (list stream form) args))
  269.   )
  270.  
  271. (provide 'stream)
  272. ;;; sgml.ol -- objective lisp interface to SGML
  273. ;;; $Id$
  274. ;;;
  275.  
  276. (require 'Stream)
  277.  
  278. (defClass SGML OStream
  279.   (gi-stack)
  280.   )
  281.  
  282. (defMethod SGML :empty (gi &optional attrs)
  283.   [self :format "<~A" gi]
  284.   (dolist (a attrs)
  285.       (let ((n (first a))
  286.         (v (second a))
  287.         )
  288.         [self :format " ~A=\"~A\"" n v])
  289.       )
  290.   [self :format ">"]
  291.   )
  292.  
  293. (defMethod SGML :start (gi &optional attrs)
  294.   (push gi gi-stack)
  295.   [self :empty gi attrs]
  296.   )
  297.  
  298. (defMethod SGML :end (gi)
  299.   (unless (eq gi (pop gi-stack))
  300.       (error "gi mismatch on" gi))
  301.   [self :format "</~A>" gi]
  302.   )
  303.  
  304. (defMethod SGML :ndata (data)
  305.   ;;@@ watch out for markup (</) in ndata!
  306.   [self :format "~A" data]
  307.   )
  308.  
  309. (defMethod SGML :end-record ()
  310.   [self :format "~%"]
  311.   )
  312.  
  313. (defMethod SGML :doctype (gi)
  314.   ;;@@ entities etc.
  315.   ;;@@ public DTD's
  316.   [self :format "<!DOCTYPE ~A SYSTEM>~%" gi]
  317.   )
  318.  
  319. (provide 'sgml)
  320. ;; mif.ol -- the Frame MIF class
  321.  
  322. (require 'objective-lisp)
  323. (require 'stream)
  324.  
  325. (defClass MIF ()
  326.   (out PgfCatalog FontCatalog VariableFormats XRefFormats
  327.        TextFlows MasterPages AFrames body hyper)
  328.   )
  329.  
  330. (defClassMethod MIF :reader (in)
  331.   [MIFReader :new in]
  332.   )
  333.  
  334. (defMethod MIF :isnew (o)
  335.   (setq out o)
  336.   )
  337.  
  338. (defClass MIFReader IStream
  339.   ()
  340.   (table)
  341.   )
  342.  
  343. (defMethod MIFReader :read ()
  344.   [self :set-readtable [self :readtable]]
  345.   (prog1 (send-super :read)
  346.     [self :set-readtable])
  347.   )
  348.  
  349. ;;;;;;;;;;;;;;;
  350. ;;; MIF Syntax
  351.  
  352. (defun read-mif-statement (f c &aux ex ret)
  353.   ;; like (read stream) but uses <> in stead of ()
  354.   (flet ((non-comment-char (comm)
  355.       ;; skip whitespace. skip comm...newline
  356.       ;; return next char
  357.       (do ((c (peek-char t f) (peek-char t f))
  358.            )
  359.           ((not (eql c comm))
  360.            c)
  361.           (read-line f)
  362.           ) )
  363.      )
  364.  
  365.     (do ()
  366.         ((eq (non-comment-char #\#) #\>))
  367.         (let ((cell (cons (read f) nil))
  368.           )
  369.           (if ex (setf (cdr ex) cell) (setf ret cell))
  370.           (setf ex cell)))
  371.     )
  372.   (read-char f) ; toss the trailing #\>
  373.   (cons ret NIL)
  374.   )
  375.  
  376. (defun read-mif-string (f c &aux ex ret nonascii)
  377.   ;; MIF strings look like `lksdjf \n \t \q \Q \x80 lksjdf'
  378.   ;;            aka        "lksdjf \n \009 ` ' \200lksjdf"
  379.   ;; returns a string if all chars are printable ASCII.
  380.   ;; returns a list of characters otherwise
  381.   (labels ((hex-digit (d)
  382.        (or (digit-char-p d)
  383.            (+ 10
  384.           (- (char-int (char-upcase d))
  385.              (char-int #\A))))
  386.        )
  387.  
  388.        (read-mif-char (f)
  389.        ;; interpret mif escapes
  390.        (let ((c (read-char f))
  391.          )
  392.          (if (eq c #\\)
  393.          (case (read-char f)
  394.                (#\> #\>) (#\q #\') (#\Q #\`) (#\\ #\\)
  395.                (#\t (setq nonascii t) (int-char 9))
  396.                (#\x (setq nonascii t)
  397.             (let ((d1 (read-char f))
  398.                   (d2 (read-char f))
  399.                   )
  400.               (read-char f) ;; skip trailing blank
  401.               (int-char (+ (* 16 (hex-digit d1))
  402.                        (hex-digit d2) ))
  403.               ))
  404.                )
  405.            c) ) )
  406.        )
  407.  
  408.       (do ()
  409.           ((eq (peek-char nil f) #\'))
  410.           (let ((cell (cons (read-mif-char f) nil))
  411.             )
  412.         (if ex (setf (cdr ex) cell) (setf ret cell))
  413.         (setf ex cell)))
  414.       (read-char f) ; toss the trailing #\'
  415.       (cons (concatenate (if nonascii 'cons 'string) ret) NIL)
  416.       ) )
  417.  
  418. (defun read-mif-inset (f c &aux ex ret)
  419.   ;; a mif inset looks like:
  420.   ;; =FrameImage
  421.   ;; &lksjdflskdjflsdkj
  422.   ;; &lksdjflsdkjflsdkjf
  423.   ;; =EndInset
  424.   ;;
  425.   (setf ret (setf ex (cons (read f) nil))) ;; read =symbol
  426.   (do ()
  427.       ((not (eq (peek-char t f) #\&)))
  428.       (read-char f) ;; skip &
  429.       (let ((cell (cons (read-line f) nil))
  430.         )
  431.     (setf (cdr ex) cell)
  432.     (setf ex cell)))
  433.   (cons ret NIL))
  434.  
  435. (defMethod MifReader :readtable ()
  436.   (or table
  437.       (progn
  438.     (setq table (subseq *readtable* 0))
  439.     (flet ((setchar (c v)
  440.             (setf (aref table (char-int c))
  441.                   v) )
  442.            )
  443.           (setchar #\< (cons :tmacro #'read-mif-statement))
  444.           (setchar #\` (cons :tmacro #'read-mif-string))
  445.           (setchar #\= (cons :tmacro #'read-mif-inset))
  446.                     ; # is the MIF comment char
  447.           (setchar #\# (aref table (char-int #\;)))
  448.                     ; signal errors on >'s
  449.           (setchar #\>
  450.                (cons :tmacro
  451.                  (lambda (f c)
  452.                    (error "misplaced right angle bracket"))) )
  453.                     ; quote is short for IN, i.e. inch
  454.           (setchar #\" (cons :tmacro
  455.                  (lambda (f c)
  456.                    (cons 'in nil) ) ))
  457.           )
  458.     table
  459.     ) ) )
  460.  
  461. (provide 'Mif)
  462. ;; mifrw.l -- convert Frame MIF
  463. ;;
  464. ;; $Id: mifrw.ol,v 1.2 92/11/17 21:59:38 connolly Exp $
  465. ;;
  466. ;; @@ marks hacks, kludges, and broken code
  467. ;; @# marks heuristics and approximations
  468. ;;
  469.  
  470. (require 'common)
  471. (require 'objective-lisp)
  472. (require 'mif)
  473.  
  474. (defMethod MIFReader :load (m)
  475.   (do ((statement [self :read] [self :read])
  476.        )
  477.       ((null statement)
  478.        )
  479.  
  480.       (format *trace-output* "~A "  (first statement))
  481.  
  482.       [m (first statement) statement]
  483.       )
  484.   )
  485.  
  486. (defMethod MIF MIFFile (statement) )
  487. (defMethod MIF Comment (statement) )
  488. (defMethod MIF Units (statement) )
  489. (defMethod MIF Verbose (statement) )
  490. (defMethod Mif ConditionCatalog (statement)  )
  491. ;(defMethod MIF PgfCatalog (statement) )
  492. ;(defMethod MIF FontCatalog (statement) )
  493. (defMethod Mif TblCatalog (statement)  )
  494. (defMethod Mif RulingCatalog (statement)  )
  495. ;(defMethod Mif VariableFormats (statement) )
  496. ;(defMethod Mif XRefFormats (statement) )
  497. (defMethod Mif Document (statement)  )
  498. (defMethod Mif BookComponent (statement)  )
  499. (defMethod Mif Dictionary (statement)  )
  500. ;(defMethod Mif AFrames (statement) )
  501. (defMethod Mif Tbls (statement)  )
  502. (defMethod MIF Page (statement) )
  503. (defMethod MIF TextFlow (statement) )
  504.  
  505.  
  506. (defClass Catalog ()
  507.   (entries)
  508.   )
  509.  
  510. (defMethod Catalog :enter (key val)
  511.   (push (cons key val) entries)
  512.   )
  513.  
  514. (defMethod Catalog :lookup (key)
  515.   (cdr (assoc key entries))
  516.   )
  517.  
  518. (defMethod MIF PgfCatalog (statement)
  519.   (setq PgfCatalog [Catalog :new])
  520.   (dolist (entry (rest statement))
  521.       [PgfCatalog :enter (get-name '(PgfTag) entry) entry]
  522.       )
  523.   )
  524.  
  525. (defMethod MIF FontCatalog (statement)
  526.   (setq FontCatalog [Catalog :new])
  527.   (dolist (entry (rest statement))
  528.       [FontCatalog :enter (get-name '(FTag) entry) entry]
  529.       )
  530.   )
  531.  
  532. (defMethod Mif VariableFormats (statement) 
  533.   (setq VariableFormats [Catalog :new])
  534.   (dolist (format (rest statement))
  535.       (let ((name (get-name '(VariableName) format))
  536.         (def (get-data '(VariableDef) format))
  537.         )
  538.         [VariableFormats :enter name def]
  539.         ) )
  540.   )
  541.  
  542. (defMethod Mif XRefFormats (statement)
  543.   (setq XRefFormats [Catalog :new])
  544.   (dolist (format (rest statement))
  545.       (let ((name (get-name '(XRefName) format))
  546.         (def (get-data '(XRefDef) format))
  547.         )
  548.         [XRefFormats :enter name def]
  549.         ) )
  550.   )
  551.         
  552. (defMethod Mif AFrames (statement)
  553.   (setq AFrames [Catalog :new])
  554.   (dolist (entry (rest statement))
  555.       [AFrames :enter (get-data '(ID) entry) entry]
  556.       )
  557.   )
  558.    
  559. ;;;;;;;;;;;;;
  560. ;; utlities
  561.  
  562. (defun find-data (tokens statements)
  563.   ;; example: (find-data '(Para ParaLine TextRectID) (rest textflow))
  564.   ;;   will find the first Para statement in the textflow,
  565.   ;;        find the first ParaLine statement in the para,
  566.   ;;        and find the first TextRectID therein.
  567.   ;;        returns the rest of the TextRectID statemnt, e.g.: (12)
  568.   (if (null tokens) statements
  569.     (do* ((target (first tokens))
  570.       (s statements (rest s))
  571.      )
  572.     ((null s) nil)
  573.     (let ((candidate (first (first s)) (first (first s)))
  574.           (result (rest (first s)) (rest (first s)))
  575.           )
  576.       (if (eq candidate target)
  577.           (return (find-data (rest tokens) result)) )
  578.       )
  579.     ) ) )
  580.  
  581. (defun get-data (tokens statement)
  582.   (first (find-data tokens (rest statement)))
  583.   )
  584.  
  585. (defun get-name (tokens statement)
  586.   (let ((s (get-data tokens statement))
  587.     )
  588.     (cond ((equal s "") nil)
  589.       (s (intern s))
  590.       )
  591.     )
  592.   )
  593.  
  594. (defun find-statements (token statement)
  595.   (remove-if-not #'(lambda (s)
  596.              (eq token (first s))
  597.              )
  598.          (rest statement))
  599.   )
  600.  
  601. (defun twips (measure)
  602.   (if (consp measure)
  603.       (let ((n (first measure))
  604.         (u (and (rest measure) (second measure)))
  605.         )
  606.     (truncate (* n (case u
  607.                  (in 1440)
  608.                  (pt 20)
  609.                  (cm (* 1440 2.54))
  610.                  (pica (/ 1440 12))
  611.                  ))) )
  612.     0) )
  613.  
  614.  
  615. ;;;;;;;;;;;;;;;;;;;;
  616. ;; special MIF routines
  617. ;; that maintain state for RTF routines
  618. ;; (should be subclass)
  619. ;;
  620.  
  621. (defMethod MIF Page (statement)
  622.   (or MasterPages (setq MasterPages [Catalog :new])) ;; should be in :isnew
  623.   (let ((type (get-data '(PageType) statement))
  624.     (tag (get-name '(PageTag) statement))
  625.     )
  626.     (case type
  627.       (BodyPage (push statement body))
  628.       ((LeftMasterPage RightMasterPage OtherMasterPage)
  629.        [MasterPages :enter tag statement] )
  630.       ;; @# ReferencePage, HiddenPage
  631.       ) )
  632.   )
  633.  
  634. (defMethod MIF :body-pages ()
  635.   (reverse body)
  636.   )
  637.  
  638. (defMethod MIF TextFlow (statement)
  639.   (or TextFlows (setq TextFlows [Catalog :new])) ;; should be in :isnew
  640.   [TextFlows :enter (get-data '(Para ParaLine TextRectID) statement) statement]
  641.   )
  642.  
  643. (defMethod Mif :write-pages ()
  644.   (dolist (page [self :body-pages])
  645.       [self :write-frame 
  646.         [MasterPages :lookup (get-name '(PageBackground) page)]]
  647.       ;; no output unless there's something there!
  648.       (when [self :write-frame page]
  649.         [out :end-section]
  650.         (format *trace-output* "!~%" )
  651.         )
  652.       ) )
  653.  
  654. (defMethod MIF :write-frame (frame &aux output)
  655.   ;;@@ sort objects by brect?
  656.   (dolist (object (rest frame))
  657.       (case (first object)
  658.         (Frame [self :write-frame object])
  659.         ;;@@(TextLine [self :write-textline object])
  660.         (ImportObject
  661.            [self :write-image object (get-data '(AnchorAlign) frame)] )
  662.         (TextRect
  663.          (let* ((id (get-data '(id) object))
  664.             (flow [TextFlows :lookup id])
  665.             (tag (get-data '(tftag) flow))
  666.             )
  667.            (when flow
  668.              [self :write-textflow flow]
  669.              (setq output t)
  670.              )
  671.            ) )
  672.         ) )
  673.   output
  674.   )
  675.  
  676. (defMethod  MIF :write-image (image &optional align)
  677.   (let ((image (find-data '(FrameImage) (rest image)))
  678.     )
  679.     (and image [out :raster 'MifVec image align])
  680.     ) )
  681.  
  682. (defMethod MIF :write-textflow (textflow)
  683.   ;;@@footnotes
  684.   ;;@@(setq hyper nil)
  685.   (dolist (s (rest textflow))
  686.       (case (first s)
  687.         (Para [self :write-para s])
  688.         ) )
  689.   )
  690.  
  691. (defMethod MIF :write-para (para)
  692.   ;; AFrames and Tbls before the paragraph
  693.   [self :write-floats para '(Top Left Near)]
  694.   
  695.   (let* ((local-format (find-data '(Pgf) (rest para)))
  696.      (tag (or (get-name '(PgfTag) para)
  697.           (get-name '(Pgf PgfTag) para)))
  698.      (tag-format (and tag [PgfCatalog :lookup tag]))
  699.      (pgfnumstring (get-data '(PgfNumString) para))
  700.      (pgfnumberfont (or (get-name '(PgfNumberFont) local-format)
  701.                 (and tag (get-name '(PgfNumberFont)
  702.                            tag-format)) ))
  703.      )
  704.  
  705.     (when tag
  706.       [out :reset-paragraph-format tag tag-format]
  707.       [out :reset-character-format nil (get-data '(PgfFont) tag-format)]
  708.       )
  709.  
  710.     (when local-format
  711.       [out :change-paragraph-format local-format]
  712.       [out :change-character-format (get-data '(PgfFont) local-format)] )
  713.  
  714.     (when pgfnumstring
  715.       [out :save-character-format]
  716.       (if pgfnumberfont
  717.           [out :reset-character-format
  718.            pgfnumberfont
  719.            [FontCatalog :lookup pgfnumberfont]])
  720.       [self :write-string pgfnumstring]
  721.       [out :restore-character-format])
  722.     )
  723.   
  724.   ;; Elements of the para
  725.   (dolist (paraline (rest para))
  726.       (case (first paraline)
  727.         (ParaLine
  728.          ;;@@ HACK! RTF widget doesn't do blank lines right!
  729.          (when (null (rest paraline))
  730.                [out :ascii " "] )
  731.          
  732.          (dolist (s (rest paraline))
  733.              (case (first s)
  734.                    ((Font PgfFont)
  735.                 ;;@@[self :end-hyper]
  736.                 [out :change-character-format s] )
  737.                    (String [self :write-string (second s)]
  738.                        ;;@@[self :hyper-not-empty]
  739.                        )
  740.                    (Char
  741.                 (case (second s)
  742.                       (Tab [out :tab])
  743.                       (HardSpace [out :ascii " "]) ;;@@
  744.                       (HardReturn [out :newline])
  745.                       (t (ignore s)) ) )
  746.                    (FNote (ignore s)) ;;@@
  747.                    (Marker [out :marker
  748.                         (get-data '(MType) s)
  749.                         (get-data '(MText) s)])
  750.                    (Variable
  751.                 [out :ndata
  752.                      [VariableFormats :lookup
  753.                               (get-name '(VariableName)
  754.                                 v)]] )
  755.                    ;;@@(XRef)
  756.                    ) )
  757.          [out :end-record]
  758.          ) )
  759.       )
  760.   
  761.   ;;@@[self :end-hyper]
  762.   [out :end-paragraph]
  763.   (princ "." *trace-output*)
  764.   
  765.   ;; AFrames and tables after the para
  766.   [self :write-floats para '(Inline Below Bottom Right Far)]
  767.   )
  768.  
  769. (defMethod MIF :write-floats (para places)
  770.   (dolist (paraline (rest para))
  771.       (when (eq (first paraline) 'ParaLine)
  772.         (dolist (s (rest paraline))
  773.             (case (first s)
  774.                   (AFrame
  775.                    (let* ((id (second s))
  776.                       (frame [AFrames :lookup id])
  777.                       (placement (get-data '(FrameType) frame))
  778.                       )
  779.                  (if (member placement places)
  780.                      [self :write-frame frame])
  781.                  ) ) ) ) ) ) )
  782.  
  783. (defMethod MIF :write-string (s)
  784.   (case (type-of s)
  785.     (string [out :ascii s])
  786.     (cons [out :mif-chars s])
  787.     ) )
  788.  
  789. ;;;;;;;;;;;
  790. ;; methods with explicit RTF knowledge
  791. ;;
  792.  
  793. (defun format-marker (stream m)
  794.   (let ((type (get-data '(MType) m))
  795.     (text (get-data '(MText) m))
  796.     )
  797.     (case type
  798.       ;;@# 0, 1, 3, 4, 5, 6, 7
  799.       (2 (format stream "{\\v{\\xe ")
  800.          (format-string stream text)
  801.          (format stream "}}")
  802.          )
  803.       (8 (format stream "{\\field{\\fldrslt ")
  804.          (setq *HyperLink* (list nil text))
  805.          )
  806.       )
  807.     ) )
  808.  
  809. (defun ignore (s)
  810.   (pprint s *error-output*)
  811.   )
  812.  
  813. (provide 'mifrw)
  814. ;;; html.ol -- objective lisp support for the WWW HTML format
  815. ;;; $Id: html.ol,v 1.2 92/11/17 21:59:51 connolly Exp $
  816. ;;;
  817.  
  818. (require 'SGML)
  819.  
  820. (defClass HTML SGML
  821.   (ignore anchor-content)
  822.   )
  823.  
  824. (defMethod HTML :ascii (data)
  825.   ;; @@ watch out for </ in CDATA
  826.   (cond (ignore)
  827.     ((member (first gi-stack) '(XMP LISTING))
  828.      [self :format "~A" data]
  829.      )
  830.     (t
  831.      (flet ((sgml-markup (c)
  832.                  (member c '(#\& #\<)) )
  833.         )
  834.            (do* ((p (position-if #'sgml-markup data)
  835.             (position-if #'sgml-markup data))
  836.              )
  837.             ((null p)
  838.              [self :format "~A" data]
  839.              )
  840.             [self :format "~A&~A;" (subseq data 0 p)
  841.               (case (elt data p)
  842.                 (#\& '|amp|)
  843.                 (#\< '|lt|)
  844.                 )]
  845.             (setq data (subseq data (1+ p)))
  846.             ) )
  847.      ) )
  848.   (setq anchor-content t)
  849.   )
  850.  
  851. (defMethod HTML :end-record ()
  852.   ;; nothing
  853.   )
  854.  
  855. (defMethod HTML :started (gi)
  856.   (or (member gi gi-stack)
  857.       [self :start gi])
  858.   )
  859.  
  860. (defMethod HTML :ended (gi)
  861.   (do ()
  862.       ((null (member gi gi-stack)))
  863.       [self :end (first gi-stack)]
  864.       (send-super :end-record)
  865.       ) )
  866.  
  867. (defMethod HTML :restore (gi)
  868.   (do ()
  869.       ((eq gi (first gi-stack)))
  870.       [self :end (first gi-stack)]
  871.       (send-super :end-record)
  872.       ) )
  873.  
  874. (defMethod HTML :reset-paragraph-format (tag fmt)
  875.   (cond ((eq tag 'TITLE)
  876.      [self :started tag]
  877.      )
  878.     ((null (eq tag (first gi-stack)))
  879.      [self :started 'document]
  880.      [self :restore 'document]
  881.      [self :started tag])
  882.     )
  883.   (case tag
  884.     ((DIR MENU OL UL)
  885.      [self :empty 'LI])
  886.     (DL
  887.      [self :empty 'DT]
  888.      )
  889.   ) )
  890.  
  891. (defMethod HTML :reset-character-format (tag foo)
  892.   [self :end-anchor]
  893.   )
  894. (defMethod HTML :change-paragraph-format (foo)
  895.   )
  896. (defMethod HTML :change-character-format (foo)
  897.   [self :end-anchor]
  898.   )
  899. (defMethod HTML :save-character-format ()
  900.   (setq ignore t)
  901.   )
  902. (defMethod HTML :restore-character-format ()
  903.   (setq ignore nil)
  904.   )
  905.  
  906. (defMethod HTML :end-paragraph ()
  907.   [self :end-anchor]
  908.   (case (first gi-stack)
  909.     
  910.     (document
  911.      [self :empty 'P]
  912.      (send-super :end-record))
  913.     ((ul ol dir menu dl)
  914.      ;;nothing
  915.      )
  916.     (t [self :end (first gi-stack)]
  917.        (send-super :end-record))
  918.   ))
  919.  
  920. (defMethod HTML :end-section ()
  921.   [self :ended 'DOCUMENT]
  922.   )
  923.  
  924. (defMethod HTML :tab ()
  925.   [self :end-anchor]
  926.   (case (first gi-stack)
  927.     (DL
  928.      [self :empty 'DD]
  929.      )
  930.     ) )
  931.  
  932. (defMethod HTML :newline ()
  933.   (case (first gi-stack)
  934.     ((XMP LISTING)
  935.      (send-super :end-record)
  936.      )
  937.     ) )
  938.  
  939. (defMethod HTML :start-anchor (name href &aux attrs)
  940.   (if name (push `(name ,name) attrs))
  941.   (if href (push `(href ,href) attrs))
  942.   [self :start 'a attrs]
  943.   (setq anchor-content nil)
  944.   )
  945.  
  946. (defMethod HTML :end-anchor ()
  947.   (if anchor-content [self :ended 'a])
  948.   )
  949.  
  950. (defMethod HTML :mif-chars (chars)
  951.   ;; @@ watch out for </ in CDATA
  952.   (or ignore
  953.       (dolist (c chars)
  954.           (let ((i (char-int c))
  955.             (cdata (member (first gi-stack) '(XMP LISTING)))
  956.             )
  957.         [self :format "~A"
  958.               (cond ((and (null cdata) (eq c #\&)) "&")
  959.                 ((and (null cdata) (eq c #\<)) "<")
  960.                 ((< i 32) "_") ;;@@
  961.                 ((< i 128) c)
  962.                 (t (aref *FrameCharacterSet* (- i 128)))
  963.                 ) ] )
  964.           ) ) )
  965.  
  966. (setq *FrameCharacterSet*
  967.   #(
  968. |Adieresis| |Aring| |Ccedilla| |Eacute| 
  969. |Ntilde| |Odieresis| |Udieresis| |aacute| |agrave| 
  970. |acircumflex| |adieresis| |atilde| |aring| |ccedilla| 
  971. |eacute| |egrave| |ecircumflex| |edieresis| |iacute| 
  972. |igrave| |icircumflex| |idieresis| |ntilde| |oacute| 
  973. |ograve| |ocircumflex| |odieresis| |otilde| |uacute| 
  974. |ugrave| |ucircumflex| |udieresis| |dagger| nil |cent| 
  975. |sterling| |section| "*" |paragraph| |germandbls| 
  976. "(R)" "(C)" "(TM)" |acute| |dieresis| 
  977. nil |AE| |Oslash| nil nil nil nil |yen| nil nil nil 
  978. nil nil nil |ordfeminine| |ordmasculine| nil |ae| |oslash| 
  979. |questiondown| |exclamdown| |logicalnot| nil |florin| 
  980. nil nil |guillemotleft| |guillemotright| |ellipsis| 
  981. nil |Agrave| |Atilde| |Otilde| |OE| |oe| "-" "--" 
  982. "``" "''" "`" "'" 
  983. nil nil |ydieresis| |Ydieresis| |fraction| "$"
  984. "<" ">" "fi" "fl" |daggerdbl| 
  985. "*" "," ",," |perthousand| 
  986. |Acircumflex| |Ecircumflex| |Aacute| |Edieresis| |Egrave| 
  987. |Iacute| |Icircumflex| |Idieresis| |Igrave| |Oacute| 
  988. |Ocircumflex| nil |Ograve| |Uacute| |Ucircumflex| |Ugrave| 
  989. |dotlessi| |circumflex| "~" |macron| |breve| |dotaccent| 
  990. |ring| |cedilla| |hungarumlaut| |ogonek| |caron| 
  991.     ) )
  992.  
  993. (defMethod HTML :marker (type text)
  994.   (case type
  995.     (8 (let* ((str (make-string-input-stream text))
  996.           (command (read str))
  997.           )
  998.          (case command
  999.            (newlink (peek-char t str)
  1000.                 [self :start-anchor (read-line str) nil])
  1001.            (gotolink [self :start-anchor nil (read-href str)])
  1002.            (message (let ((client (read str))
  1003.                   )
  1004.                   (peek-char t str) ;; skip whitespace
  1005.                   (case client
  1006.                     (www [self :start-anchor nil
  1007.                            (read-line str)] )
  1008.                     ) ))
  1009.            )
  1010.          ))
  1011.     ) )
  1012.  
  1013. (defun read-href (str)
  1014.   ;; parse foo:bar -> file:foo#bar
  1015.   ;;       bar -> #bar
  1016.   ;;       foo:firstpage -> file:foo
  1017.   (peek-char t str)
  1018.   (do (file
  1019.        anchor ex
  1020.        href
  1021.        (char (read-char str) (read-char str))
  1022.        )
  1023.       ((null char) ;; reached end of string
  1024.        (if file
  1025.        (setq href (concatenate 'string "file:" file)) )
  1026.        (cond ((null anchor) )
  1027.          ((eq 'firstpage (intern (concatenate 'string anchor))) )
  1028.          (t (setq href (concatenate 'string href "#"
  1029.                     anchor) )) )
  1030.        href
  1031.        )
  1032.       
  1033.       ;; body of do loop...
  1034.       (case char
  1035.         (#\: (setq file anchor)
  1036.          (setq anchor nil)
  1037.          (setq ex nil) )
  1038.         (t (let ((cell (cons char nil))
  1039.              )
  1040.          (if ex (setf (cdr ex) cell)
  1041.            (setf anchor cell) )
  1042.          (setf ex cell) ))
  1043.         )
  1044.       ) )
  1045.  
  1046. (provide 'html)
  1047. ;; mif2html.ol -- convert Frame interchange format to HTML
  1048. (require 'mifrw)
  1049. (require 'html)
  1050.  
  1051. (setq x [MifReader :new *standard-input*])
  1052. (setq z [HTML :new *standard-output*])
  1053. (setq y [MIF :new z])
  1054. [x :load y]
  1055. [y :write-pages]
  1056.  
  1057. (exit)
  1058.